package com.company.loganalyzer.service;

import com.company.loganalyzer.service.LLMService.ToolSelectionResult;
import com.company.loganalyzer.service.LLMService.AnalysisResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 日志分析智能体服务
 * 
 * 核心智能体，负责：
 * 1. 自然语言查询理解
 * 2. 工具选择和编排
 * 3. 结果综合和格式化
 * 4. 对话上下文管理
 */
@Service
public class LogAnalyzerAgentService {
    
    private static final Logger logger = LoggerFactory.getLogger(LogAnalyzerAgentService.class);
    
    @Autowired
    private LLMService llmService;
    
    private final RestTemplate restTemplate;
    private final Map<String, ConversationSession> sessions;
    
    // 可用工具列表
    private static final List<String> AVAILABLE_TOOLS = Arrays.asList(
        "search_logs",
        "analyze_errors", 
        "get_log_statistics",
        "trace_error_context",
        "trace_analysis"
    );
    
    public LogAnalyzerAgentService() {
        this.restTemplate = new RestTemplate();
        this.sessions = new HashMap<>();
    }
    
    /**
     * 智能查询处理
     * 
     * @param query 用户自然语言查询
     * @param sessionId 会话ID（可选）
     * @return 分析结果
     */
    public AgentQueryResponse processQuery(String query, String sessionId) {
        try {
            logger.info("处理智能查询: {}, 会话ID: {}", query, sessionId);
            
            // 1. 获取或创建会话
            ConversationSession session = getOrCreateSession(sessionId);
            
            // 2. 意图分析和工具选择
            ToolSelectionResult toolSelection = llmService.analyzeAndSelectTools(query, AVAILABLE_TOOLS);
            logger.info("选择的工具: {}", toolSelection.getSelectedTools());
            
            // 3. 执行选定的工具
            Map<String, Object> toolResults = executeSelectedTools(toolSelection, query);
            
            // 4. 结果综合
            AnalysisResponse analysis = llmService.synthesizeResponse(query, toolResults);
            
            // 5. 更新会话上下文
            updateSessionContext(session, query, toolSelection, toolResults, analysis);
            
            // 6. 构建响应
            return buildAgentResponse(query, toolSelection, toolResults, analysis, session);
            
        } catch (Exception e) {
            logger.error("智能查询处理失败: {}", e.getMessage(), e);
            return AgentQueryResponse.error("查询处理失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取会话信息
     */
    public ConversationSession getSession(String sessionId) {
        return sessions.get(sessionId);
    }
    
    /**
     * 清除会话
     */
    public void clearSession(String sessionId) {
        sessions.remove(sessionId);
    }
    
    /**
     * 获取智能体状态
     */
    public AgentStatus getAgentStatus() {
        return AgentStatus.builder()
            .name("日志分析智能体")
            .version("2.0.0")
            .llmAvailable(llmService.isAvailable())
            .availableTools(AVAILABLE_TOOLS)
            .activeSessions(sessions.size())
            .timestamp(LocalDateTime.now())
            .build();
    }
    
    private ConversationSession getOrCreateSession(String sessionId) {
        if (sessionId == null || sessionId.isEmpty()) {
            sessionId = "session-" + System.currentTimeMillis();
        }
        
        return sessions.computeIfAbsent(sessionId, id -> new ConversationSession(id));
    }
    
    private Map<String, Object> executeSelectedTools(ToolSelectionResult toolSelection, String query) {
        Map<String, Object> results = new HashMap<>();
        
        for (String toolName : toolSelection.getSelectedTools()) {
            try {
                Object result = executeToolAPI(toolName, toolSelection.getExtractedParameters(), query);
                results.put(toolName, result);
                logger.info("工具 {} 执行成功", toolName);
            } catch (Exception e) {
                logger.warn("工具 {} 执行失败: {}", toolName, e.getMessage());
                results.put(toolName, Map.of("error", e.getMessage(), "status", "failed"));
            }
        }
        
        return results;
    }
    
    private Object executeToolAPI(String toolName, Map<String, Object> parameters, String query) {
        // 构建工具API请求
        String apiUrl = "http://localhost:8080/api/v1/log-analysis/tools/" + toolName;
        
        Map<String, Object> requestBody = new HashMap<>(parameters);
        
        // 根据工具类型设置默认参数
        switch (toolName) {
            case "search_logs":
                requestBody.putIfAbsent("query", extractSearchQuery(query));
                requestBody.putIfAbsent("timeRange", "last_24h");
                requestBody.putIfAbsent("limit", 100);
                break;
            case "analyze_errors":
                requestBody.putIfAbsent("timeRange", "last_24h");
                break;
            case "get_log_statistics":
                requestBody.putIfAbsent("timeRange", "last_24h");
                requestBody.putIfAbsent("groupBy", Arrays.asList("level"));
                break;
            case "trace_error_context":
                requestBody.putIfAbsent("timeRange", "last_24h");
                break;
        }
        
        try {
            return restTemplate.postForObject(apiUrl, requestBody, Object.class);
        } catch (Exception e) {
            throw new RuntimeException("工具API调用失败: " + e.getMessage());
        }
    }
    
    private String extractSearchQuery(String naturalQuery) {
        // 简单的查询提取逻辑
        String lower = naturalQuery.toLowerCase();
        if (lower.contains("error") || lower.contains("错误")) {
            return "ERROR";
        } else if (lower.contains("exception") || lower.contains("异常")) {
            return "Exception";
        } else if (lower.contains("warn") || lower.contains("警告")) {
            return "WARN";
        }
        return ""; // 返回空字符串表示搜索全部
    }
    
    private void updateSessionContext(ConversationSession session, String query, 
                                    ToolSelectionResult toolSelection, 
                                    Map<String, Object> toolResults,
                                    AnalysisResponse analysis) {
        ConversationTurn turn = ConversationTurn.builder()
            .query(query)
            .selectedTools(toolSelection.getSelectedTools())
            .toolResults(toolResults)
            .analysis(analysis)
            .timestamp(LocalDateTime.now())
            .build();
            
        session.addTurn(turn);
    }
    
    private AgentQueryResponse buildAgentResponse(String query, 
                                                ToolSelectionResult toolSelection,
                                                Map<String, Object> toolResults,
                                                AnalysisResponse analysis,
                                                ConversationSession session) {
        return AgentQueryResponse.builder()
            .query(query)
            .sessionId(session.getSessionId())
            .selectedTools(toolSelection.getSelectedTools())
            .reasoning(toolSelection.getReasoning())
            .toolResults(toolResults)
            .summary(analysis.getSummary())
            .analysis(analysis.getAnalysis())
            .recommendations(analysis.getRecommendations())
            .timestamp(LocalDateTime.now())
            .status("success")
            .build();
    }
    
    // 内部数据类
    public static class ConversationSession {
        private final String sessionId;
        private final List<ConversationTurn> turns;
        private final LocalDateTime createdAt;
        
        public ConversationSession(String sessionId) {
            this.sessionId = sessionId;
            this.turns = new ArrayList<>();
            this.createdAt = LocalDateTime.now();
        }
        
        public void addTurn(ConversationTurn turn) {
            turns.add(turn);
            // 保持最近10轮对话
            if (turns.size() > 10) {
                turns.remove(0);
            }
        }
        
        // Getters
        public String getSessionId() { return sessionId; }
        public List<ConversationTurn> getTurns() { return turns; }
        public LocalDateTime getCreatedAt() { return createdAt; }
    }
    
    public static class ConversationTurn {
        private String query;
        private List<String> selectedTools;
        private Map<String, Object> toolResults;
        private AnalysisResponse analysis;
        private LocalDateTime timestamp;
        
        public static ConversationTurnBuilder builder() {
            return new ConversationTurnBuilder();
        }
        
        public static class ConversationTurnBuilder {
            private ConversationTurn turn = new ConversationTurn();
            
            public ConversationTurnBuilder query(String query) {
                turn.query = query;
                return this;
            }
            
            public ConversationTurnBuilder selectedTools(List<String> selectedTools) {
                turn.selectedTools = selectedTools;
                return this;
            }
            
            public ConversationTurnBuilder toolResults(Map<String, Object> toolResults) {
                turn.toolResults = toolResults;
                return this;
            }
            
            public ConversationTurnBuilder analysis(AnalysisResponse analysis) {
                turn.analysis = analysis;
                return this;
            }
            
            public ConversationTurnBuilder timestamp(LocalDateTime timestamp) {
                turn.timestamp = timestamp;
                return this;
            }
            
            public ConversationTurn build() {
                return turn;
            }
        }
    }
    
    public static class AgentQueryResponse {
        private String query;
        private String sessionId;
        private List<String> selectedTools;
        private String reasoning;
        private Map<String, Object> toolResults;
        private String summary;
        private String analysis;
        private List<String> recommendations;
        private LocalDateTime timestamp;
        private String status;
        
        public static AgentQueryResponseBuilder builder() {
            return new AgentQueryResponseBuilder();
        }
        
        public static AgentQueryResponse error(String message) {
            return builder()
                .status("error")
                .analysis(message)
                .timestamp(LocalDateTime.now())
                .build();
        }
        
        // Getters
        public String getQuery() { return query; }
        public String getSessionId() { return sessionId; }
        public List<String> getSelectedTools() { return selectedTools; }
        public String getReasoning() { return reasoning; }
        public Map<String, Object> getToolResults() { return toolResults; }
        public String getSummary() { return summary; }
        public String getAnalysis() { return analysis; }
        public List<String> getRecommendations() { return recommendations; }
        public LocalDateTime getTimestamp() { return timestamp; }
        public String getStatus() { return status; }
        
        public static class AgentQueryResponseBuilder {
            private AgentQueryResponse response = new AgentQueryResponse();
            
            public AgentQueryResponseBuilder query(String query) {
                response.query = query;
                return this;
            }
            
            public AgentQueryResponseBuilder sessionId(String sessionId) {
                response.sessionId = sessionId;
                return this;
            }
            
            public AgentQueryResponseBuilder selectedTools(List<String> selectedTools) {
                response.selectedTools = selectedTools;
                return this;
            }
            
            public AgentQueryResponseBuilder reasoning(String reasoning) {
                response.reasoning = reasoning;
                return this;
            }
            
            public AgentQueryResponseBuilder toolResults(Map<String, Object> toolResults) {
                response.toolResults = toolResults;
                return this;
            }
            
            public AgentQueryResponseBuilder summary(String summary) {
                response.summary = summary;
                return this;
            }
            
            public AgentQueryResponseBuilder analysis(String analysis) {
                response.analysis = analysis;
                return this;
            }
            
            public AgentQueryResponseBuilder recommendations(List<String> recommendations) {
                response.recommendations = recommendations;
                return this;
            }
            
            public AgentQueryResponseBuilder timestamp(LocalDateTime timestamp) {
                response.timestamp = timestamp;
                return this;
            }
            
            public AgentQueryResponseBuilder status(String status) {
                response.status = status;
                return this;
            }
            
            public AgentQueryResponse build() {
                return response;
            }
        }
    }
    
    public static class AgentStatus {
        private String name;
        private String version;
        private boolean llmAvailable;
        private List<String> availableTools;
        private int activeSessions;
        private LocalDateTime timestamp;
        
        public static AgentStatusBuilder builder() {
            return new AgentStatusBuilder();
        }
        
        // Getters
        public String getName() { return name; }
        public String getVersion() { return version; }
        public boolean isLlmAvailable() { return llmAvailable; }
        public List<String> getAvailableTools() { return availableTools; }
        public int getActiveSessions() { return activeSessions; }
        public LocalDateTime getTimestamp() { return timestamp; }
        
        public static class AgentStatusBuilder {
            private AgentStatus status = new AgentStatus();
            
            public AgentStatusBuilder name(String name) {
                status.name = name;
                return this;
            }
            
            public AgentStatusBuilder version(String version) {
                status.version = version;
                return this;
            }
            
            public AgentStatusBuilder llmAvailable(boolean llmAvailable) {
                status.llmAvailable = llmAvailable;
                return this;
            }
            
            public AgentStatusBuilder availableTools(List<String> availableTools) {
                status.availableTools = availableTools;
                return this;
            }
            
            public AgentStatusBuilder activeSessions(int activeSessions) {
                status.activeSessions = activeSessions;
                return this;
            }
            
            public AgentStatusBuilder timestamp(LocalDateTime timestamp) {
                status.timestamp = timestamp;
                return this;
            }
            
            public AgentStatus build() {
                return status;
            }
        }
    }
}